﻿using Microsoft.Extensions.Configuration;
using Mohe.Scada.Util.Exceptions;
using NLog;
using System.Text.Json;

namespace Mohe.Scada.Util.Helper
{
    /// <summary>注入的配置文件获取</summary>
    public class ConfigHelper
    {
        private static readonly NLog.ILogger logger;

        /// <summary>配置文件</summary>
        public static IConfiguration configuration;

        static ConfigHelper()
        {
            try
            {
                logger = LogManager.GetCurrentClassLogger();
            }
            catch (Exception ex)
            {
                logger.Error(ex, "没有从容器中获取到configuration上下文，配置文件帮助类需要调用Ini初始化");
            }
        }

        /// <summary>获取指定的配置节点</summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetValue<T>(string key, T defaultValue = default)
        {
            try
            {
                return configuration.GetSection(key).Get<T>();
            }
            catch (Exception)
            {
                if (defaultValue != null) return defaultValue;

                throw new FatalException("配置（" + key + "）不存在", "配置不存在");
            }
        }

        /// <summary>获取指定的配置节点</summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetValue(string key, string defaultValue = "")
        {
            try
            {
                return configuration.GetSection(key).Get<string>();
            }
            catch (Exception)
            {
                if (!string.IsNullOrEmpty(defaultValue)) return defaultValue;
                throw new FatalException("配置（" + key + "）不存在", "配置不存在");
            }
        }

        /// <summary>初始化</summary>
        /// <param name="jsonFiles">json配置文件</param>
        /// <param name="optional">文件是否可选</param>
        /// <param name="reloadOnChange">是否在文件内容发生变化时重新加载</param>
        /// <exception cref="System.IO.IOException">文件不存在</exception>
        /// <returns>IConfiguration 对象</returns>
        public static void Init(string[] jsonFiles, bool optional = false, bool reloadOnChange = true)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder();
            if (jsonFiles != null)
            {
                foreach (String jsonFile in jsonFiles)
                {
                    builder.AddJsonFile(jsonFile, optional, reloadOnChange);
                }
            }
            configuration = builder.Build();
        }

        /// <summary>初始化</summary>
        /// <param name="_configuration"></param>
        public static void Init(IConfiguration _configuration)
        {
            configuration = _configuration;
        }

        /// <summary>获取节对象</summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IConfigurationSection GetSection(string key)
        {
            return configuration.GetSection(key);
        }

        /// <summary>获取key</summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetConfigurationValue(string key)
        {
            return configuration[key];
        }

        /// <summary>获取节中的key</summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetConfigurationValue(string section, string key)
        {
            return GetSection(section)?[key];
        }

        public static void SetValue(string key, string value)
        {
            configuration[key] = value;
        }

        public static void Save(string file = "app.json")
        {
            var configObject = new Dictionary<string, object>();

            foreach (var section in configuration.GetChildren())
            {
                AddSection(configObject, section);
            }
            string jsonStr = JsonSerializer.Serialize(configObject, new JsonSerializerOptions { WriteIndented = true });
            File.WriteAllText(file, jsonStr);
        }

        private static void AddSection(Dictionary<string, object> parent, IConfigurationSection section)
        {
            var children = section.GetChildren().ToList();
            if (!children.Any())
            {
                // 叶子节点（非数组元素）
                parent[section.Key] = section.Value;
                return;
            }

            // 检查是否为数组：所有子节点的键是数字索引（0,1,2...）
            bool isArray = children.All(c => int.TryParse(c.Key, out _));
            if (isArray)
            {
                var array = new List<object>();
                // 按索引排序
                foreach (var child in children.OrderBy(c => int.Parse(c.Key)))
                {
                    // 数组元素可能是复杂对象或简单值
                    if (child.GetChildren().Any())
                    {
                        var childDict = new Dictionary<string, object>();
                        AddSection(childDict, child);
                        foreach (var key in childDict.Keys)
                        {
                            array.Add(childDict[key]);
                        }

                    }
                    else
                    {
                        array.Add(child.Value);
                    }
                }
                parent[section.Key] = array;
            }
            else
            {
                // 非数组，作为嵌套对象处理
                var childDict = new Dictionary<string, object>();
                parent[section.Key] = childDict;
                foreach (var child in children)
                {
                    AddSection(childDict, child);
                }
            }
        }
    }
}
